﻿using Assimp;
using OpenTK.Mathematics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OpenTKBasics.AssimpNet
{
    public class Model
    { 
        private List<Mesh> meshes = new List<Mesh>();
        private Shader _shader;

        public Model(Shader shader, string path)
        {
            this._shader = shader;
            LoadModel(path);
        }
         
        void LoadModel(string path)
        {

            AssimpOperator assimpOperator = new AssimpOperator();
            assimpOperator.LoadFile(path);
            meshes = assimpOperator.meshes.Select(m => ProcessMesh(m)).ToList();
        }

        Mesh ProcessMesh(Assimp.Mesh mesh)
        {
            List<Vertex> tempVertices = new List<Vertex>();
            List<uint> tempIndices = new List<uint>();
            List<Texture> tempTextures = new List<Texture>();

            //Vector3 tempVec;

            for (int i = 0; i < mesh.VertexCount; i++)
            {
                Vertex tempVertex = new Vertex();

                Vector3D vert = mesh.Vertices[i];
                tempVertex.Position.X = vert.X;
                tempVertex.Position.Y = vert.Y;
                tempVertex.Position.Z = vert.Z;

                Vector3D norm = mesh.Normals[i];
                tempVertex.Normal.X = norm.X;
                tempVertex.Normal.Y = norm.Y;
                tempVertex.Normal.Z = norm.Z;

                if (mesh.HasTextureCoords(0))
                {
                    tempVertex.TexCoords.X = mesh.TextureCoordinateChannels[0][i].X;
                    tempVertex.TexCoords.Y = mesh.TextureCoordinateChannels[0][i].Y;
                }
                else
                {
                    tempVertex.TexCoords = new Vector2(0.0f, 0.0f);
                }
                 
                tempVertices.Add(tempVertex);
            }

            //foreach (int i in mesh.Faces.SelectMany(f => f.Indices))
            //{
            //    tempIndices.Add((uint)i);
            //}

            for (int i = 0; i < mesh.FaceCount; i++)
            {
                for (int j = 0; j < mesh.Faces[i].IndexCount; j++)
                {
                    tempIndices.Add((uint)mesh.Faces[i].Indices[j]);
                }
            }

            //Mesh myMesh = new Mesh(this._shader,tempVertices.ToArray(), tempIndices.ToArray(), new Texture[0]);
            //myMesh.SetShader(this._shader);

            return new Mesh(this._shader, tempVertices.ToArray(), tempIndices.ToArray(), tempTextures.ToArray() );
        }

       public void Draw()
        {
            meshes.ForEach(m => m.Draw());
        }

    }
}
